package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(3)
	go func() {
		defer wg.Done()
		//do something
		time.Sleep(2 * time.Second)
		fmt.Println("func1 done")
	}()

	go func() {
		defer wg.Done()
		// do something
		time.Sleep(2 * time.Second)
		fmt.Println("func2 done")
	}()

	go func() {
		defer wg.Done()
		// do something
		time.Sleep(2 * time.Second)
		fmt.Println("func3 done")
	}()

	wg.Wait()

	fmt.Println("main done")
}

//processAndGather 当有多个goroutine向同一个通道写入时，我们需要确保被写入的通道只被关闭一次
func processAndGather(in <-chan int, processor func(int) int, num int) []int {
	out := make(chan int, num)
	var wg sync.WaitGroup
	wg.Add(num)
	for i := 0; i < num; i++ {
		go func() {
			defer wg.Done()
			for V := range in {
				out <- V
			}
		}()
	}

	go func() {
		wg.Wait()
		close(out)
	}()
	var result []int
	for v := range out {
		result = append(result, v)
	}
	return result
}
